/* ****************************************************************************
 *
 * Copyright (c) Microsoft Corporation. 
 *
 * This source code is subject to terms and conditions of the Microsoft Public License. A 
 * copy of the license can be found in the License.html file at the root of this distribution. If 
 * you cannot locate the  Microsoft Public License, please send an email to 
 * dlr@microsoft.com. By using this source code in any fashion, you are agreeing to be bound 
 * by the terms of the Microsoft Public License.
 *
 * You must not remove this notice, or any other, from this software.
 *
 * THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
 * KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
 * PARTICULAR PURPOSE.
 * ***************************************************************************/


#if !defined(AFX_PGLTEXTUREBRUSH_H__5E525701_AB18_497B_906D_E727768B1267__INCLUDED_)
#define AFX_PGLTEXTUREBRUSH_H__5E525701_AB18_497B_906D_E727768B1267__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#include <pgl/core/PGLBrush.h>
#include <pgl/core/PGLImage.h>

/*! \brief Image based brush

	A brush based on a bitmap. 

  \ingroup PGLBrushGroup
*/
class PGLCORE_EXT_CLASS CPGLTextureBrush : public CPGLBrush  
{
PGL_DECLARE_DYNCREATE(CPGLTextureBrush);
public:
	//! specifies how repeated copies of an image are used to tile an area
	enum EWrapMode
	{
		//! Tiling without flipping
		WrapModeTile=1,
		//! Tiles are flipped horizontally as you move from one tile to the next in a row
		WrapModeTileFlipX=2,
		//! Tiles are flipped vertically as you move from one tile to the next in a column
		WrapModeTileFlipY=3,
		//! Tiles are flipped horizontally as you move along a row and flipped vertically as you move along a column
		WrapModeTileFlipXY=4,
		//! No tiling takes place
		WrapModeClamp=5
	};
	
public:
	//! \name Constructors
	//@{
	//! Default constructor
	CPGLTextureBrush(LPCTSTR szFileName = NULL, const CPGLRectD& rBBox = CPGLRectD::GetNormBox());
	//! Copy constructor
	CPGLTextureBrush(const CPGLTextureBrush& brush)	{*this = brush;};
	//! Assignment constructor
	CPGLTextureBrush& operator = (const CPGLTextureBrush& brush);
	//! Desctructor
	virtual ~CPGLTextureBrush();
	//@}

	//! \name Image manipulation
	//@{
	/*! \brief Loading image from a file.

	The extension of szFileName determines the type of image. Accepted types of images are:
		- jpg 
		- png 
		- bmp 
		- tiff

	\param szFileName Pointer to a null-terminated string that specifies the path name of the image file. 
	\return true if loading succesfull.

	Note that a call to load function, will always unload the previous bitmap (if any).

	\sa CPGLImage::Load
	*/
	bool Load(LPCTSTR szFileName, bool bUpdateArea = true)		{ return m_image.Load(szFileName, true);};

	/*! \brief Loading image from ressource

	\param IDResource ressource ID
	\param hInstance Handle to an instance of a module whose executable file contains a bitmap resource. If NULL, AfxGetInstanceHandle() is used.
	\return true if loading succesfull.

	\sa CPGLImage::Load
	*/
	bool Load(DWORD IDResource, HINSTANCE hInstance = NULL, bool bUpdateArea = true) { return m_image.Load(IDResource, hInstance, true);};

	/*! \brief Loading image from BITMAPINFO

	\param gdiBitmapInfo  Pointer to a GDI BITMAPINFO structure. This structure defines several bitmap attributes, such as size and pixel format. The BITMAPINFO structure is defined in Wingdi.h.
	\param gdiBitmapData, Pointer to an array of bytes that contains the pixel data. 
	\return true if loading succesfull.

	\sa CPGLImage::Load
	*/
	bool Load( const BITMAPINFO* gdiBitmapInfo, VOID* gdiBitmapData)	{ return m_image.Load(gdiBitmapInfo, gdiBitmapData, true);};

	/*! Unload image

	\return true if unloading succesfull.
	*/
	bool UnLoad()						{	return m_image.UnLoad();};
	//! returns reference to image object, const
	const CPGLImage& GetImage() const	{	return m_image;};
	//! returns reference to image object
	CPGLImage& GetImage()				{	return m_image;};
	//@}

	//! \name Wrapping mode
	//@{
	//! Set Wrap mode
	void SetWrapMode(EWrapMode eWrapMode)	{	m_eWrapMode = eWrapMode;};
	//! returns wrap mode
	EWrapMode GetWrapMode() const			{	return m_eWrapMode;};
	//@}	

	//! \name Plotting functions
	//@{
	//! Make brush current in graphic interface
	virtual void MakeCurrentFill(gfxinterface::CGfxInterface& gfx);
	//@}

	//! \name Serialization and debugging
	//@{
	//! Serialize functions
	virtual void SerializeXML(CPGLArchive& ar);
	//! Convert EWrapMode to string
	CString WrapModeToString(EWrapMode eWrapMode);
	//! Convert string to wrap mode
	EWrapMode StringToWrapMode(LPCTSTR szWrapMode);
	//! Debuggin functions
	#ifdef _DEBUG
	    virtual void Dump( CDumpContext& dc ) const;
	    virtual void AssertValid() const;  
	#endif
	//@}
protected:
	//! \name Attributes
	//@{
	//! Bitmap
	CPGLImage m_image;
	//! Wrap mode
	EWrapMode m_eWrapMode;
	//@}

	static gfxinterface::ETextureWrapMode GetGfxWrapMode(EWrapMode eWrapMode);
};

PGL_DECLARE_SMARTPTR( CPGLTextureBrush );

#endif // !defined(AFX_PGLTEXTUREBRUSH_H__5E525701_AB18_497B_906D_E727768B1267__INCLUDED_)
